package com.paramInjector;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class ParamClass {
	private Map<Class, Object> classMap = new HashMap<Class, Object>(128);
	private ParamInjector paramInjector;
	public ParamClass() {
		put(this.getClass(), this);
	}
	
	public ParamClass(ParamInjector paramInjector) {
		this();
		this.paramInjector = paramInjector;
	}

	public void put(Class clazz,Object value){
		classMap.put(clazz, value);
	}
	public void put(Object value){
		if(value!=null){
			classMap.put(value.getClass(), value);
		}
	}
	
	final Object[] zero={};
	public Object[] getParams(AccessibleObject executable){
		Class[] paramClasses = null;
		Annotation[][] parameterannotationarr2 = null;
		if(executable instanceof Method){
			paramClasses = ((Method)executable).getParameterTypes();
			parameterannotationarr2 = ((Method)executable).getParameterAnnotations();
		}else if(executable instanceof Constructor){
			paramClasses = ((Constructor)executable).getParameterTypes();
			parameterannotationarr2 = ((Constructor)executable).getParameterAnnotations();
		}
		if(paramClasses == null||paramClasses.length==0){
			return zero;
		}
		
		Object[] params = new Object[paramClasses.length];
		ParameterAnnotations parameterAnnotations = new ParameterAnnotations(parameterannotationarr2);
		// 方法注解
		MethodAnnotation methodAnnotation = new MethodAnnotation(executable.getDeclaredAnnotations());
		for (int i = 0; i < paramClasses.length; i++) {
			// 参数注解
			ParameterAnnotation parameterAnnotation = parameterAnnotations.getParameterAnnotation(i);
			Class paramClass = paramClasses[i];
			Object param = null;
			if(paramInjector!=null){
				param = paramInjector.getObject(executable, paramClass, methodAnnotation, parameterAnnotation,this);
			}
			if(param == null){
				param = classMap.get(paramClass);
			}
			if(param == null){
				param = getDefault(paramClass);
			}
			params[i] = param;
		}
		return params;
	}
	
	public Object getDefault(Class paramClass){
		if(Number.class.isAssignableFrom(paramClass)){
			return 0;
		}
		if(paramClass.isPrimitive()){
			if(paramClass == Boolean.class||paramClass == boolean.class){
				return false;
			}
			return 0;
		}
		
		return null;
	}
	public static void main(String[] args) {
		System.out.println(Number.class.isAssignableFrom(Integer.class));

	}
}
